<?php
namespace App\Console\Commands;

use Illuminate\Console\Command;
use \Qiniu\Auth;
use \Qiniu\Storage\BucketManager;
class FetchKLog extends Command
{
    protected $signature = "fetch:klog";

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = "fetch k log from qiniu";


    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $accessKey = config('qiniu.ak');
        $secretKey = config('qiniu.sk');
        $logBucket = config('qiniu.bucket.log');
        $logDomain = config('qiniu.domain.log');
        $auth = new Auth($accessKey, $secretKey);
        $bucketManager = new BucketManager($auth);
        $cpmDate = date("Ymd");
        $cpmHour = date("H");
        $prefix = "kcnt" . date('Y-m-d-H-');
        $this->info($prefix);
        $marker = '';
        $limit = 100;
        $delimiter = '/';
        list($ret, $err) = $bucketManager->listFiles($logBucket, $prefix, $marker, $limit, $delimiter);
        $hourBeginTs = strtotime(date('Y-m-d H:00:00'));
        // $this->info($hourBegin);
        $this->info(date('Y-m-d H:00:00'));
        if (!empty($err)) {
            $this->error(json_decode($err, JSON_PRETTY_PRINT));
        } else {
            $items = $ret['items'];
            $dataByFiveMinutes = [];
            if (!empty($items)) {
                foreach ($items as $key => $value) {
                    $putTime = $value['putTime'];
                    $putTimeTs = intval($putTime / 10000000);
                    $timeInterval = $putTimeTs - $hourBeginTs;
                    $num = intval($timeInterval / 300) + ($timeInterval % 300 > 200 ? 1 :0) - 1;
                    $dataByFiveMinutes[$num][] = $auth->privateDownloadUrl("http://{$logDomain}/{$value['key']}");
                }
            }
            $klogDataByFiveMinutes = [];
            foreach($dataByFiveMinutes as $num => $urls) {
                foreach ($urls as $url) {
                    $rawData = file_get_contents($url);
                    if (!empty($rawData)) {
                        $data = explode("\n", trim($rawData));
                        $data = array_map(function($v){return json_decode($v, true);}, $data);
                    }

                    $klogDataByFiveMinutes[$num] = array_merge($klogDataByFiveMinutes[$num] ?? [], $data);
                }
            }
            $adEvents = [];

            $positionList = \App\Model\AdPosition::all();
            $positionCodeList = $positionList->pluck('identifier')->toArray();
            $adEvents = [];
            foreach($positionCodeList as $positionCode) {
                $adEvents[] = $positionCode . "_action_show";
                $adEvents[] = $positionCode . "_action_click";
            }
            $adEventsLog = [];
            $planidList = [];
            foreach($klogDataByFiveMinutes as $interval => $logs) {
                foreach($logs as $log) {
                    if (in_array($log['raw_k'], $adEvents)) {
                        $planid = $log['raw_planid'];
                        if (!empty($planid)) {
                            $planidList[] = $planid;
                            $dataKey = $log['raw_k'] .'_'. $log['raw_v0'] . '_' . $planid;
                        } else {
                            $dataKey = $log['raw_k'] .'_'. $log['raw_v0'];
                        }
                        $adEventsLog['log_' . $interval][$dataKey] = $log;

                    }
                }
            }
            // $this->info(json_encode($adEventsLog, JSON_PRETTY_PRINT));
            // die();
            $providerList = \App\Model\AdProvider::all();
            $ctrResult = [];
            foreach($adEventsLog as $interval => $log) {
                $cpmInterval = explode("_", $interval)[1];
                foreach($positionList as $position) {
                    $positionCode = $position->identifier;
                    foreach($providerList as $provider) {
                        $showKey = $positionCode . '_action_show_'. $provider->identifier;
                        $clickKey = $positionCode . '_action_click_' . $provider->identifier;
                        if ($provider->type == 0) {
                            foreach ($planidList as $planid) {
                                $show = $log[$showKey . '_' . $planid]['cnt'] ?? null;
                                $click = $log[$clickKey . '_' . $planid]['cnt'] ?? null;

                                if ($show === null){
                                    $ctr = -1;
                                } else {
                                    $ctr = intval(ceil(($click / $show) * 1000));
                                }
                                $ctrResult[$interval][$positionCode][$provider->identifier . '_' . $planid] = $ctr;
                                $cpc = \App\Model\AdCost::where('ad_provider_id', $provider->id)->where('ad_position_id', $position->id)->first();
                                if (empty($cpc)) {
                                    \Log::error("[FetchKLog] cpc empty provider:{$provider->id}\tposition:{$position->id}");
                                }
                                if ($ctr != -1) {
                                    $cpmVal = $ctr * $cpc->cost;
                                } else {
                                    $cpmVal = -1;
                                }
                                \App\Model\Cpm::firstOrCreate([
                                    'cpm_date'  =>  $cpmDate,
                                    'cpm_hour'  =>  $cpmHour,
                                    'cpm_interval'  =>  $cpmInterval,
                                    'ad_position_id'    =>  $position->id,
                                    'ad_provider_id'    =>  $provider->id,
                                    'planid'    =>  $planid,
                                ],[
                                    'ctr_val'   =>  $ctr,
                                    'cpm_val'   =>  $cpmVal,
                                ]);
                            }
                        } else {
                            $show = $log[$showKey]['cnt'] ?? null;
                            $click = $log[$clickKey]['cnt'] ?? null;

                            if ($show === null){
                                $ctr = -1;
                            } else {
                                $ctr = intval(ceil(($click / $show) * 1000));
                            }
                            $ctrResult[$interval][$positionCode][$provider->identifier] = $ctr;
                            $cpc = \App\Model\AdCost::where('ad_provider_id', $provider->id)->where('ad_position_id', $position->id)->first();
                            if (empty($cpc)) {
                                \Log::error("[FetchKLog] cpc empty provider:{$provider->id}\tposition:{$position->id}");
                            }
                            if ($ctr != -1) {
                                $cpmVal = $ctr * $cpc->cost;
                            } else {
                                $cpmVal = -1;
                            }
                            \App\Model\Cpm::firstOrCreate([
                                'cpm_date'  =>  $cpmDate,
                                'cpm_hour'  =>  $cpmHour,
                                'cpm_interval'  =>  $cpmInterval,
                                'ad_position_id'    =>  $position->id,
                                'ad_provider_id'    =>  $provider->id,
                                'planid'    =>  0,
                            ],[
                                'ctr_val'   =>  $ctr,
                                'cpm_val'   =>  $cpmVal,
                            ]);
                        }
                    }
                }
            }
        }
    }
}